// QCodeEditor
#include <QCXXExtracter>

// Qt
#include <QRegularExpression>

QCXXExtracter::QCXXExtracter(QObject *parent) :
    QSymbolExtracter(parent)
{
    initCXXKeywords();
}

QStringList QCXXExtracter::extractSymbols(const QString& code)
{
    if (code.isEmpty()) {
        return QStringList();
    }

    QStringList symbolList;
    
    // 清空对象-类型映射
    m_objectTypes.clear();
    m_classMembers.clear();
    m_symbolsInfo.clear();
    m_currentNamespaces.clear();
    
    // 添加C++关键字到符号列表
    symbolList.append(m_cxxKeywords);
    
    // 提取不同类型的符号
    extractNamespaces(code, symbolList);
    extractClasses(code, symbolList);
    extractFunctions(code, symbolList);
    extractVariables(code, symbolList);
    extractIncludes(code, symbolList);
    
    // 提取对象类型关系
    extractObjectTypes(code);
    
    // 计算符号位置信息
    extractSymbolPositions(code);
    
    // 移除重复项并排序
    symbolList.removeDuplicates();
    symbolList.sort();
    
    // 更新成员变量
    m_symbols = symbolList;
    
    // 发出信号通知符号列表已更新
    emit symbolsUpdated(m_symbols);
    emit symbolsInfoUpdated(m_symbolsInfo);
    
    return m_symbols;
}

QStringList QCXXExtracter::symbols() const
{
    return m_symbols;
}

QStringList QCXXExtracter::getObjectMembers(const QString& objectName) const
{
    QStringList members;
    
    // 尝试直接获取类成员（如果objectName本身是类）
    for (const auto& pair : m_classMembers.toStdMap()) {
        if (pair.first == objectName) {
            members.append(pair.second);
        }
    }
    
    // 如果没有找到成员（即objectName不是类），尝试获取对象的类型
    if (members.isEmpty()) {
        // 获取对象的类型
        QString className = m_objectTypes.value(objectName);
        
        if (!className.isEmpty()) {
            // 获取该类的所有成员
            for (const auto& pair : m_classMembers.toStdMap()) {
                if (pair.first == className) {
                    members.append(pair.second);
                }
            }
        }
    }
    
    // 如果仍然没有找到成员，检查是否是C++内置类型
    if (members.isEmpty()) {
        // 为常见的C++内置类型添加默认成员
        if (objectName == "std::string" || objectName == "string") {
            members << "c_str" << "size" << "empty" << "clear" << "substr" << "find" << "append";
        } else if (objectName == "std::vector" || objectName.contains("vector")) {
            members << "push_back" << "pop_back" << "size" << "empty" << "clear" << "reserve" << "resize";
        } else if (objectName == "std::map" || objectName.contains("map")) {
            members << "insert" << "find" << "erase" << "size" << "empty" << "clear" << "count";
        } else if (objectName == "QObject") {
            members << "parent" << "children" << "setObjectName" << "objectName" << "connect" << "disconnect";
        } else if (objectName == "QWidget") {
            members << "show" << "hide" << "setVisible" << "update" << "repaint" << "close" << "resize";
        }
    }
    
    // 移除重复项
    members.removeDuplicates();
    
    return members;
}

QString QCXXExtracter::getObjectType(const QString& objectName) const
{
    // 直接从对象-类型映射中获取
    QString type = m_objectTypes.value(objectName);
    
    return type;
}

QMap<QString, QString> QCXXExtracter::getObjectTypesMap() const
{
    return m_objectTypes;
}

QList<SymbolInfo> QCXXExtracter::getSymbolsInfo() const
{
    return m_symbolsInfo;
}

SymbolInfo QCXXExtracter::getSymbolInfoAtPosition(int line, int column) const
{
    // 查找位于给定行列位置的符号
    for (const SymbolInfo& info : m_symbolsInfo) {
        if (info.line == line && 
            column >= info.column && 
            column < (info.column + info.length)) {
            return info;
        }
    }
    
    // 没有找到，返回空的SymbolInfo
    return SymbolInfo();
}

void QCXXExtracter::initCXXKeywords()
{
    // C++关键字列表
    m_cxxKeywords << "alignas" << "alignof" << "and" << "and_eq" << "asm" << "auto"
                << "bitand" << "bitor" << "bool" << "break" << "case" << "catch"
                << "char" << "char8_t" << "char16_t" << "char32_t" << "class" << "compl"
                << "concept" << "const" << "consteval" << "constexpr" << "constinit" << "const_cast"
                << "continue" << "co_await" << "co_return" << "co_yield" << "decltype" << "default"
                << "delete" << "do" << "double" << "dynamic_cast" << "else" << "enum"
                << "explicit" << "export" << "extern" << "false" << "float" << "for"
                << "friend" << "goto" << "if" << "inline" << "int" << "long"
                << "mutable" << "namespace" << "new" << "noexcept" << "not" << "not_eq"
                << "nullptr" << "operator" << "or" << "or_eq" << "private" << "protected"
                << "public" << "register" << "reinterpret_cast" << "requires" << "return" << "short"
                << "signed" << "sizeof" << "static" << "static_assert" << "static_cast" << "struct"
                << "switch" << "template" << "this" << "thread_local" << "throw" << "true"
                << "try" << "typedef" << "typeid" << "typename" << "union" << "unsigned"
                << "using" << "virtual" << "void" << "volatile" << "wchar_t" << "while"
                << "xor" << "xor_eq";
    
    // 常用预处理指令
    m_cxxKeywords << "#include" << "#define" << "#ifdef" << "#ifndef" << "#endif"
                << "#if" << "#else" << "#elif" << "#pragma" << "#undef";
    
    // 常用STL容器
    m_cxxKeywords << "std::string" << "std::vector" << "std::map" << "std::set"
                << "std::list" << "std::deque" << "std::queue" << "std::stack"
                << "std::array" << "std::unordered_map" << "std::unordered_set";
    
    // 常用Qt类
    m_cxxKeywords << "QString" << "QList" << "QVector" << "QMap" << "QSet"
                << "QObject" << "QWidget" << "QDialog" << "QMainWindow" << "QApplication";
}

void QCXXExtracter::extractNamespaces(const QString& code, QStringList& symbols)
{
    // 匹配命名空间定义: namespace Name { 或 namespace Name::SubName {
    QRegularExpression namespaceRegex(R"(namespace\s+([A-Za-z_][A-Za-z0-9_:]*)\s*\{)");
    QRegularExpressionMatchIterator matches = namespaceRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString namespaceName = match.captured(1);
        
        // 添加到符号列表
        symbols << namespaceName;
        
        // 记录当前命名空间
        if (!m_currentNamespaces.contains(namespaceName)) {
            m_currentNamespaces.append(namespaceName);
        }
    }
}

void QCXXExtracter::extractClasses(const QString& code, QStringList& symbols)
{
    // 匹配类定义: class/struct ClassName [: BaseClass] {
    QRegularExpression classRegex(R"((class|struct)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^{]*)?\{)");
    QRegularExpressionMatchIterator matches = classRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString className = match.captured(2);
        
        // 添加到符号列表
        symbols << className;
        
        // 提取类的位置
        int classPos = match.capturedStart();
        
        // 找到类定义的结束位置
        int endPos = findClassEnd(code, classPos);
        
        if (endPos > classPos) {
            // 提取类的代码块
            QString classCode = code.mid(classPos, endPos - classPos);
            
            // 提取类的方法和属性
            QStringList classMembers;
            extractClassMembers(className, classCode, classMembers);
        }
    }
}

int QCXXExtracter::findClassEnd(const QString& code, int startPos)
{
    // 找到类定义的开始大括号
    int openBracePos = code.indexOf('{', startPos);
    if (openBracePos == -1) return code.length();
    
    // 查找匹配的右大括号
    int braceCount = 1;
    int pos = openBracePos + 1;
    
    while (pos < code.length() && braceCount > 0) {
        if (code.at(pos) == '{') {
            braceCount++;
        } else if (code.at(pos) == '}') {
            braceCount--;
            if (braceCount == 0) {
                return pos + 1; // 返回结束位置
            }
        }
        pos++;
    }
    
    return code.length();
}

void QCXXExtracter::extractClassMembers(const QString& className, const QString& classCode, QStringList& members)
{
    // 提取方法: 返回类型 方法名(参数)
    QRegularExpression methodRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\))");
    QRegularExpressionMatchIterator methodMatches = methodRegex.globalMatch(classCode);
    
    while (methodMatches.hasNext()) {
        QRegularExpressionMatch match = methodMatches.next();
        
        // 检查这不是变量声明
        int pos = match.capturedEnd();
        while (pos < classCode.length() && classCode.at(pos).isSpace()) pos++;
        
        // 如果后面紧跟着';'，这是一个变量声明，跳过
        if (pos < classCode.length() && classCode.at(pos) == ';') continue;
        
        QString returnType = match.captured(1);
        QString methodName = match.captured(2);
        QString parameters = match.captured(3).trimmed();
        
        // 过滤掉构造函数和析构函数，保留普通方法
        if (methodName != className && !methodName.startsWith('~')) {
            members << methodName;
            m_classMembers.insert(className, methodName);
            
            // 保存参数信息
            m_functionParameters[className + "::" + methodName] = parameters;
        }
    }
    
    // 提取构造函数和析构函数
    QRegularExpression ctorRegex(R"(\b)" + className + R"(\s*\(([^)]*)\))");
    QRegularExpressionMatch ctorMatch = ctorRegex.match(classCode);
    if (ctorMatch.hasMatch()) {
        members << className;
        m_classMembers.insert(className, className);
        m_functionParameters[className + "::" + className] = ctorMatch.captured(1).trimmed();
    }
    
    QRegularExpression dtorRegex(R"(~\s*)" + className + R"(\s*\(\s*\))");
    if (dtorRegex.match(classCode).hasMatch()) {
        members << "~" + className;
        m_classMembers.insert(className, "~" + className);
    }
    
    // 提取成员变量
    QRegularExpression memberRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*;)");
    QRegularExpressionMatchIterator memberMatches = memberRegex.globalMatch(classCode);
    
    while (memberMatches.hasNext()) {
        QRegularExpressionMatch match = memberMatches.next();
        QString memberType = match.captured(1);
        QString memberName = match.captured(2);
        
        // 过滤掉关键字
        if (!m_cxxKeywords.contains(memberName) && !memberName.isEmpty()) {
            members << memberName;
            m_classMembers.insert(className, memberName);
            
            // 记录成员变量类型
            m_objectTypes[className + "::" + memberName] = memberType;
        }
    }
}

QString QCXXExtracter::findClassForPosition(const QString& code, int position)
{
    // 获取position之前的代码段
    QString beforeCode = code.left(position);
    
    // 从position向前查找最近的类定义
    QRegularExpression classRegex(R"((class|struct)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^{]*)?\{)");
    QRegularExpressionMatchIterator matches = classRegex.globalMatch(beforeCode);
    
    QString lastClassName;
    int lastPos = -1;
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        if (match.capturedStart() > lastPos) {
            lastPos = match.capturedStart();
            lastClassName = match.captured(2);
        }
    }
    
    // 检查position是否在该类的范围内
    if (!lastClassName.isEmpty() && lastPos >= 0) {
        int endPos = findClassEnd(code, lastPos);
        if (position < endPos) {
            return lastClassName;
        }
    }
    
    return QString();
}

void QCXXExtracter::extractFunctions(const QString& code, QStringList& symbols)
{
    // 匹配函数定义: 返回类型 函数名(参数) {
    QRegularExpression funcRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)\s*(?:const|override|final|noexcept)?\s*\{)");
    QRegularExpressionMatchIterator matches = funcRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString returnType = match.captured(1);
        QString funcName = match.captured(2);
        QString parameters = match.captured(3).trimmed();
        
        // 检查是否是类方法（即在类内部）
        int pos = match.capturedStart();
        QString className = findClassForPosition(code, pos);
        
        // 如果不在类内部，则是全局函数
        if (className.isEmpty()) {
            // 添加到符号列表
            symbols << funcName;
            
            // 保存参数信息
            m_functionParameters[funcName] = parameters;
        }
    }
}

void QCXXExtracter::extractVariables(const QString& code, QStringList& symbols)
{
    // 匹配全局变量定义: 类型 变量名[=初始值];
    QRegularExpression varRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:=\s*[^;]+)?\s*;)");
    QRegularExpressionMatchIterator matches = varRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString varType = match.captured(1);
        QString varName = match.captured(2);
        
        // 检查是否在类内部
        int pos = match.capturedStart();
        QString className = findClassForPosition(code, pos);
        
        // 如果不在类内部，则是全局变量
        if (className.isEmpty() && !m_cxxKeywords.contains(varName)) {
            // 添加到符号列表
            symbols << varName;
            
            // 记录变量类型
            m_objectTypes[varName] = varType;
        }
    }
}

void QCXXExtracter::extractIncludes(const QString& code, QStringList& symbols)
{
    // 匹配包含指令: #include <file> 或 #include "file"
    QRegularExpression includeRegex(R"(#include\s+[<"]([^>"]+)[>"])");
    QRegularExpressionMatchIterator matches = includeRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString includeFile = match.captured(1);
        
        // 从包含文件名中提取可能的符号（简化处理）
        QStringList parts = includeFile.split('.');
        if (!parts.isEmpty()) {
            QString baseName = parts.first();
            
            // 常见的库前缀映射到命名空间
            if (baseName.startsWith("q") && baseName.length() > 1) {
                // Qt类，转换为Q开头的类名
                QString className = "Q" + baseName.mid(1);
                
                // 如果不是关键字，添加到符号列表
                if (!m_cxxKeywords.contains(className)) {
                    symbols << className;
                }
            } else if (baseName.contains("std")) {
                // STL头文件，添加std命名空间
                if (!symbols.contains("std")) {
                    symbols << "std";
                }
            }
        }
    }
}

void QCXXExtracter::extractObjectTypes(const QString& code)
{
    // 匹配变量声明和初始化: 类型 变量名 = 表达式;
    QRegularExpression objRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:=\s*([^;]+))?\s*;)");
    QRegularExpressionMatchIterator matches = objRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString typeName = match.captured(1);
        QString objName = match.captured(2);
        
        // 检查是否是类成员变量
        int pos = match.capturedStart();
        QString className = findClassForPosition(code, pos);
        
        if (!className.isEmpty()) {
            // 类成员变量
            m_objectTypes[className + "::" + objName] = typeName;
        } else {
            // 局部变量或全局变量
            m_objectTypes[objName] = typeName;
        }
    }
    
    // 匹配对象创建: 变量名 = new 类型(参数);
    QRegularExpression newRegex(R"(([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\s+([A-Za-z_][A-Za-z0-9_:]*))");
    matches = newRegex.globalMatch(code);
    
    while (matches.hasNext()) {
        QRegularExpressionMatch match = matches.next();
        QString objName = match.captured(1);
        QString typeName = match.captured(2);
        
        m_objectTypes[objName] = typeName;
    }
}

void QCXXExtracter::extractSymbolPositions(const QString& code)
{
    // 清空现有的符号位置信息
    m_symbolsInfo.clear();
    
    // 用于跟踪已处理的符号，避免重复添加
    QSet<QString> processedSymbols;
    
    // 1. 添加关键字位置信息
    for (const QString& keyword : m_cxxKeywords) {
        QRegularExpression keywordRegex(QString("\\b(%1)\\b").arg(keyword));
        QRegularExpressionMatchIterator matches = keywordRegex.globalMatch(code);
        
        while (matches.hasNext()) {
            QRegularExpressionMatch match = matches.next();
            int position = match.capturedStart(1);
            int length = match.capturedLength(1);
            
            int line = 0, column = 0;
            calculateLineAndColumn(code, position, line, column);
            
            m_symbolsInfo.append(SymbolInfo(keyword, SymbolInfo::Keyword, line, column, length));
        }
    }
    
    // 2. 添加类位置信息
    QRegularExpression classRegex(R"((class|struct)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^{]*)?\{)");
    QRegularExpressionMatchIterator classMatches = classRegex.globalMatch(code);
    
    while (classMatches.hasNext()) {
        QRegularExpressionMatch match = classMatches.next();
        QString className = match.captured(2);
        
        // 类名是唯一的，只添加一次
        if (processedSymbols.contains("c:" + className)) {
            continue;
        }
        processedSymbols.insert("c:" + className);
        
        int position = match.capturedStart(2);
        int length = match.capturedLength(2);
        
        int line = 0, column = 0;
        calculateLineAndColumn(code, position, line, column);
        
        m_symbolsInfo.append(SymbolInfo(className, SymbolInfo::Class, line, column, length));
    }
    
    // 3. 添加函数位置信息
    QRegularExpression funcRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\))");
    QRegularExpressionMatchIterator funcMatches = funcRegex.globalMatch(code);
    
    while (funcMatches.hasNext()) {
        QRegularExpressionMatch match = funcMatches.next();
        QString returnType = match.captured(1);
        QString funcName = match.captured(2);
        QString parameters = match.captured(3).trimmed();
        
        // 确定函数的作用域
        int position = match.capturedStart(2);
        QString scope = findClassForPosition(code, position);
        
        // 作用域前缀，避免不同作用域中同名函数的冲突
        QString scopedName = scope.isEmpty() ? funcName : scope + "::" + funcName;
        
        // 检查是否已处理过此函数
        if (processedSymbols.contains("f:" + scopedName)) {
            continue;
        }
        processedSymbols.insert("f:" + scopedName);
        
        int length = match.capturedLength(2);
        
        int line = 0, column = 0;
        calculateLineAndColumn(code, position, line, column);
        
        m_symbolsInfo.append(SymbolInfo(funcName, SymbolInfo::Function, line, column, length, scope, parameters));
    }
    
    // 4. 添加变量位置信息
    QRegularExpression varRegex(R"(([A-Za-z_][A-Za-z0-9_:]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:=\s*[^;]+)?\s*;)");
    QRegularExpressionMatchIterator varMatches = varRegex.globalMatch(code);
    
    while (varMatches.hasNext()) {
        QRegularExpressionMatch match = varMatches.next();
        QString varType = match.captured(1);
        QString varName = match.captured(2);
        
        // 过滤掉C++关键字
        if (!m_cxxKeywords.contains(varName)) {
            int position = match.capturedStart(2);
            
            // 确定变量的作用域
            QString scope = findClassForPosition(code, position);
            
            // 作用域前缀，避免不同作用域中同名变量的冲突
            QString scopedName = scope.isEmpty() ? varName : scope + "::" + varName;
            
            // 检查是否已处理过此变量
            if (processedSymbols.contains("v:" + scopedName)) {
                continue;
            }
            processedSymbols.insert("v:" + scopedName);
            
            int length = match.capturedLength(2);
            
            int line = 0, column = 0;
            calculateLineAndColumn(code, position, line, column);
            
            m_symbolsInfo.append(SymbolInfo(varName, SymbolInfo::Variable, line, column, length, scope));
        }
    }
} 